package com.htstar.ovms.device.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.htstar.ovms.common.core.i18n.MsgCode;
import com.htstar.ovms.common.core.util.R;
import com.htstar.ovms.device.api.entity.Device;
import com.htstar.ovms.device.api.entity.DeviceOta;
import com.htstar.ovms.device.api.feign.DeviceGatewayFeign;
import com.htstar.ovms.device.api.wrapper.MessageWrapper;
import com.htstar.ovms.device.api.wrapper.OTAData;
import com.htstar.ovms.device.mapper.DeviceOtaMapper;
import com.htstar.ovms.device.service.DeviceService;
import com.htstar.ovms.device.service.OTAUpdateService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

@Service
@Slf4j
public class OTAUpdateServiceImpl extends ServiceImpl<DeviceOtaMapper, DeviceOta> implements OTAUpdateService {

    @Autowired
    DeviceOtaMapper deviceOtaMapper;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    DeviceGatewayFeign deviceGatewayFeign;

    @Autowired
    DeviceService deviceService;


    @Override
    @Transactional
    public R updateBatch(OTAData req) {
        if (req.getDeviceSnList().size() == 0) {
            return R.failed(MsgCode.SELECT_THE_DEVICE_FIRST.msg());
        }
        //升级的设备号存库
        deviceService.updateOTAStatusInit(req, 2);//2:等待中
        //查找需要升级的在线设备
//        List<DeviceOta> onlineDeviceList = baseMapper.getOnlineDevie();//所有需要升级的设备
        List<String> reqOnlineDeviceList = baseMapper.getReqOnlineDeviceList(req.getDeviceSnList());
        //需要升级的未在线设备暂时放入redis
        List<String> NoOnline = req.getDeviceSnList();
//        NoOnline.removeAll(reqOnlineDeviceList);
        //需要所有设备列表缓存redis
        for (String dn : NoOnline) {
            redisTemplate.opsForValue().set("OTAList:" + dn, req.getData());
        }
        //original
//        StringBuffer stringBuffer = new StringBuffer();
//        for (String deviceSn : NoOnline) {
//            stringBuffer.append(deviceSn).append(",");
//        }
//        String s = stringBuffer.toString();
//        String substring = s.substring(0, s.length() - 1);
//        String oldNoOnlineList = (String) redisTemplate.opsForValue().get("OTANoOnlineList");
//        redisTemplate.opsForValue().set("OTANoOnlineList", oldNoOnlineList + "," + substring);
//        redisTemplate.opsForValue().set("OTAData", req.getData());


        //调用网关处理在线设备的升级
//        if (reqOnlineDeviceList.size() > 0) {
//            OTAData otaData = new OTAData();
//            otaData.setDeviceSnList(reqOnlineDeviceList);//在线设备立即升级
//            otaData.setData(req.getData());
//            deviceGatewayFeign.updateBatch(otaData);
//        }
        return R.ok();
    }

    @Override
    public void updateHoldOn(List<String> holdONList, Integer status) {
        for (String deviceSn : holdONList) {
            DeviceOta deviceOta = new DeviceOta();
            deviceOta.setHoldOn(status);
            baseMapper.update(deviceOta, Wrappers.<DeviceOta>lambdaUpdate().eq(DeviceOta::getDeviceSn, deviceSn));
            //Wrappers.<DeviceLastData>lambdaUpdate().eq(DeviceLastData::getDeviceSn, "45785885")
        }
    }

    @Override
    public void updateFailureTime(OTAData otaData) {
        if (otaData.getDeviceSn() != null) {
            QueryWrapper<DeviceOta> deviceOtaQueryWrapper = new QueryWrapper<>();
            deviceOtaQueryWrapper.eq("device_sn", otaData.getDeviceSn());
            deviceOtaQueryWrapper.orderByDesc("id");
            DeviceOta deviceOta = baseMapper.selectOne(deviceOtaQueryWrapper);
            if (deviceOta.getFailureTime() != null && deviceOta.getFailureTime() < 3) {
                DeviceOta deviceOta1 = new DeviceOta();
                deviceOta1.setFailureTime(deviceOta.getFailureTime() + 1);
                deviceOta1.setHoldOn(0);
                baseMapper.update(deviceOta1, Wrappers.<DeviceOta>lambdaUpdate().eq(DeviceOta::getDeviceSn, otaData.getDeviceSn()));
            }
        }
    }

    @Override
    public void updateCommandSendStatus(String deviceSn, Integer status) {
        UpdateWrapper<DeviceOta> deviceOtaUpdateWrapper = new UpdateWrapper<>();
        deviceOtaUpdateWrapper.eq("device_sn", deviceSn);
        DeviceOta deviceOta = new DeviceOta();
        deviceOta.setSendResult(status);
        if (status.equals(0)) {
            deviceOta.setHoldOn(0);
        }
        baseMapper.update(deviceOta, deviceOtaUpdateWrapper);

    }

    @Override
    public void otaUpdateSuccess(String deviceSn, Integer status) {
        QueryWrapper<Device> deviceQueryWrapper = new QueryWrapper<>();
        deviceQueryWrapper.eq("device_sn", deviceSn);
        Device one = deviceService.getOne(deviceQueryWrapper);//设备列表中的该设备
        if (one != null) {
            Device device = new Device();
            device.setId(one.getId());
            device.setOtaStatus(1);
            deviceService.updateById(device);

            DeviceOta deviceOta = new DeviceOta();
            deviceOta.setId(one.getOtaId());
            deviceOta.setUpdateResult(1);
            deviceOta.setOtaStatus(1);
            baseMapper.updateById(deviceOta);
            return;
        }
        DeviceOta deviceOta2 = new DeviceOta();
        deviceOta2.setOtaStatus(1);
        UpdateWrapper<DeviceOta> deviceOtaUpdateWrapper = new UpdateWrapper<>();
        deviceOtaUpdateWrapper.eq("device_sn", deviceSn);
        deviceOtaUpdateWrapper.eq("ota_status", 2);//第次仅发一次数据，所以仅有一条等待
        baseMapper.update(deviceOta2, deviceOtaUpdateWrapper);

//        UpdateWrapper<DeviceOta> deviceOtaUpdateWrapper = new UpdateWrapper<>();
//        deviceOtaUpdateWrapper.eq("device_sn", deviceSn).set("update_result", 1);

    }

    @Override
    public boolean isRetry(String deviceSn) {
//        QueryWrapper<DeviceOta> deviceOtaQueryWrapper = new QueryWrapper<>();
//        deviceOtaQueryWrapper.eq("device_sn", deviceSn);
//        DeviceOta deviceOta = baseMapper.selectOne(deviceOtaQueryWrapper);
//        if (deviceOta.getFailureTime() < 3) {
//            return true;
//        }
////        UpdateWrapper<DeviceOta> deviceOtaUpdateWrapper = new UpdateWrapper<>();
////        deviceOtaUpdateWrapper.eq("device_sn", deviceSn).set("failure_time", deviceOta.getFailureTime() + 1);
//        DeviceOta deviceOta1 = new DeviceOta();
//        deviceOta1.setFailureTime(deviceOta.getFailureTime() + 1);
//        baseMapper.update(deviceOta1, Wrappers.<DeviceOta>lambdaUpdate().eq(DeviceOta::getDeviceSn, deviceSn));
//----------------------------------------------------------------------------------------------------------
        //失败3次以下重试
        QueryWrapper<Device> deviceQueryWrapper = new QueryWrapper<>();
        deviceQueryWrapper.eq("device_sn", deviceSn);
        Device one = deviceService.getOne(deviceQueryWrapper);
        if (one.getFailureTime() < 3) {
            UpdateWrapper<Device> deviceUpdateWrapper = new UpdateWrapper<>();
            deviceUpdateWrapper.eq("device_sn", deviceSn);
            Device device = new Device();
            device.setFailureTime(one.getFailureTime() + 1);
            device.setOtaStatus(3);//设置失败状态
            deviceService.update(device, deviceUpdateWrapper);
            //同步OTA表失败次数
            DeviceOta deviceOta = new DeviceOta();
            deviceOta.setId(one.getOtaId());
            deviceOta.setOtaStatus(3);
            deviceOta.setFailureTime(one.getFailureTime() + 1);
            baseMapper.updateById(deviceOta);
            return true;
        }
        return false;
    }

}
